/*
THIS FILE IS PART OF THE >>ADRENALIN-3D-GRAFIC-ENGINE<<
for latest info visit http://www.creative-games.de

Copyright (c) 2008-2009 by Marco Schneider

This library is free software; you can redistribute it and/or modify it
under the terms of the GNU Lesser General Public License (LGPL) as
published by the Free Software Foundation; either version 2.1 of the
License, or (at your option) any later version.

This library is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
License for more details.

*/

#ifndef __ADL_POINTER_H__
#define __ADL_POINTER_H__

#pragma once

namespace Adrenalin 
{
	class ReferenceCount
	{
	private:
		int		_counter;
	public:
		ReferenceCount()
			: _counter(0)
		{ }

		int AddReference()
		{
			return _counter++;
		}

		int ReleaseReference()
		{
			return _counter--;
		}
	};

	template<class T> class Pointer
	{
		friend class ReferenceCount;
	private:
		T*				_data;
		ReferenceCount	_referenceCounter;
	public:
		Pointer()
			: _data(NULL)
		{
			_referenceCounter->AddReference();
		}

		Pointer(T* value)
			: _data(value)
		{
			_referenceCounter->AddReference();
		}

		Pointer( const Pointer<T>& value )
			: _data(value._data), _referenceCounter._counter(value._referenceCounter._counter)
		{ }

		~Pointer()
		{
			if(_referenceCounter->Release() == 0)
			{
				delete _data;
				delete _referenceCounter;
			}
		}

		operator T*(void) 
		{ 
			return _data; 
		}

		T& operator*(void) 
		{ 
			return *_data; 
		}

		T* operator->(void) 
		{ 
			return _data; 
		}

		Pointer& operator=(Pointer<T> &p)
		{
			return operator=((T *) p);
		}
	};
};//namespace
#endif